#include "CTaskMgr.h"
#include "CValidTask.h"

#include <iostream>
#include <fstream>
#include <vector>
#include "pb_cfg_task.pb.h"
#include "../mainctrl.h"
#include "MsgComm.pb.h"

int CTaskMgr::Init()
{
    int iRet = 0;

    iRet = _stTaskConfig.Init();
    CHECK_RETURN(iRet);

    return 0;
}

int CTaskMgr::LoadConfig(const char* szLogPath)
{
    int iRet = 0;

    if (szLogPath == NULL)
    {
        CT_ERROR(("Task Log Path is null"));
        return RET_SYSTEM_FAIL;
    }

    pb_cfg_task stTaskPBConfig;
    std::fstream stFileInput(szLogPath, std::ios::in | std::ios::binary);
    if (!stTaskPBConfig.ParseFromIstream(&stFileInput))
    {
        CT_ERROR(("Failed to Parse TaskCfg!"));
        return RET_SYSTEM_FAIL;
    }

    //解析配置文件内容
    CT_TRACE(("task config count %d", stTaskPBConfig.task_config_rows_size()));
    for (int i = 0; i < stTaskPBConfig.task_config_rows_size(); ++i)
    {
        const pb_cfg_task_pb_cfg_task_config_unit& stTaskPBConfigUnit 
            = stTaskPBConfig.task_config_rows(i);

        CTaskConfigData stConfigData;
    
        //任务ID
        int iTaskID = stTaskPBConfigUnit.task_id() % TASK_CONFIG_ID_MOD;
        int iBranchID = stTaskPBConfigUnit.task_id() / TASK_CONFIG_ID_MOD;

        stConfigData._stTaskID._uiBranchID = (unsigned int)iBranchID;
        stConfigData._stTaskID._uiTaskID = (unsigned int)iTaskID;

        CT_TRACE(("任务ID %d, 分支ID %d", stConfigData._stTaskID._uiTaskID, 
                                            stConfigData._stTaskID._uiBranchID));
        
        //任务NPC
        stConfigData._iAcceptNPC = stTaskPBConfigUnit.accept_npc_id();
        stConfigData._iCommitNPC = stTaskPBConfigUnit.commit_npc_id();

        CT_TRACE(("领取NPC %d , 提交NPC %d", stConfigData._iAcceptNPC,
                                              stConfigData._iCommitNPC));

        //激活条件
        if (stTaskPBConfigUnit.open_type_1() != CTaskCond::TASK_NONE)
        {
            CTaskCond stCond;
            stCond._ucCond = stTaskPBConfigUnit.open_type_1();
            stCond._iCondData1 = stTaskPBConfigUnit.open_data_1();
            stCond._iCondData2 = 0;

            stConfigData._astOpenConds.AddOneItem(stCond);

            CT_TRACE(("激活条件1: 类型 %d , 数据 %d", stCond._ucCond,
                                            stCond._iCondData1));

            if (stTaskPBConfigUnit.open_type_2() != CTaskCond::TASK_NONE)
            {
                CTaskCond stCond;
                stCond._ucCond = stTaskPBConfigUnit.open_type_2();
                stCond._iCondData1 = stTaskPBConfigUnit.open_data_2();
                stCond._iCondData2 = 0;

                stConfigData._astOpenConds.AddOneItem(stCond);

                CT_TRACE(("激活条件2: 类型 %d , 数据 %d", stCond._ucCond,
                    stCond._iCondData1));
            }
        }

        //完成条件
        if (stTaskPBConfigUnit.finish_cond_1() != CTaskCond::TASK_NONE
            && stTaskPBConfigUnit.finish_cond_1() != CTaskCond::TASK_NCP_TALK)
        {
            CTaskCond stCond;
            stCond._ucCond = stTaskPBConfigUnit.finish_cond_1();
            stCond._iCondData1 = stTaskPBConfigUnit.finish_data1_1();
            stCond._iCondData2 = stTaskPBConfigUnit.finish_data2_1();

            stConfigData._astFinishConds.AddOneItem(stCond);

            CT_TRACE(("完成条件1: 类型 %d , 数据1 %d , 数据2 %d", stCond._ucCond,
                stCond._iCondData1, stCond._iCondData2));

            if (stTaskPBConfigUnit.finish_cond_2() != CTaskCond::TASK_NONE
                && stTaskPBConfigUnit.finish_cond_2() != CTaskCond::TASK_NCP_TALK)
            {
                CTaskCond stCond;
                stCond._ucCond = stTaskPBConfigUnit.finish_cond_2();
                stCond._iCondData1 = stTaskPBConfigUnit.finish_data1_2();
                stCond._iCondData2 = stTaskPBConfigUnit.finish_data2_2();

                stConfigData._astFinishConds.AddOneItem(stCond);

                CT_TRACE(("完成条件2: 类型 %d , 数据1 %d , 数据2 %d", stCond._ucCond,
                    stCond._iCondData1, stCond._iCondData2));
            }
        }

        //后续任务
        if (strlen(stTaskPBConfigUnit.follow_tasks().c_str()) > 0)
        {
            std::string sFollowTasks = stTaskPBConfigUnit.follow_tasks();
            const std::string sDel = ",";
            std::vector<std::string> vFollowTasks;

            CTStringUtils::Split(sFollowTasks, sDel, vFollowTasks);
            for (unsigned int i = 0; i < vFollowTasks.size(); ++i)
            {
                CTaskID stTempTaskID;
                stTempTaskID._uiTaskID = atoi(vFollowTasks[i].c_str()) % TASK_CONFIG_ID_MOD;
                stTempTaskID._uiBranchID = atoi(vFollowTasks[i].c_str()) / TASK_CONFIG_ID_MOD;

                CT_TRACE(("后续任务%u: 分支ID %d, 任务ID %d", 
                    i, stTempTaskID._uiBranchID, stTempTaskID._uiTaskID));

                stConfigData._astFollowTasks.AddOneItem(stTempTaskID);
            }
        }

	    //task award
	    if( stTaskPBConfigUnit.award_type_1() != 0 )
	    {
		    CTaskAward ctAward1;
		    ctAward1.m_iAwardType = stTaskPBConfigUnit.award_type_1();
		    ctAward1.m_iAwardData = stTaskPBConfigUnit.award_num_1();
		    string strTaskAwardId = stTaskPBConfigUnit.task_award_id_1(); //or 9999|award class set string 
		    unsigned int iAwardItemId = atoi(strTaskAwardId.c_str());
		    if( iAwardItemId==TASK_AWARD_SETCLASS )
		    {
			    ctAward1.m_strItemSet = string(strTaskAwardId.c_str(), 5, strTaskAwardId.length()-5 );
		    }
		    ctAward1.m_iAwardItemId = iAwardItemId;

		    stConfigData._astTaskAward.AddOneItem( ctAward1 );

		    if( stTaskPBConfigUnit.award_type_2() != 0 )
		    {
			    CTaskAward ctAward2;
			    ctAward2.m_iAwardType = stTaskPBConfigUnit.award_type_2();
			    ctAward2.m_iAwardData = stTaskPBConfigUnit.award_num_2();
			    string strTaskAwardId = stTaskPBConfigUnit.task_award_id_2(); //or 9999|award class set string 
			    unsigned int iAwardItemId = atoi(strTaskAwardId.c_str());
			    if( iAwardItemId==TASK_AWARD_SETCLASS )
			    {
				    ctAward2.m_strItemSet = string(strTaskAwardId.c_str(), 5, strTaskAwardId.length()-5 );
			    }
			    ctAward2.m_iAwardItemId = iAwardItemId;

			    stConfigData._astTaskAward.AddOneItem( ctAward2 );

			    if( stTaskPBConfigUnit.award_type_3() != 0 )
			    {
				    CTaskAward ctAward3;
				    ctAward3.m_iAwardType = stTaskPBConfigUnit.award_type_3();
				    ctAward3.m_iAwardData = stTaskPBConfigUnit.award_num_3();
				    string strTaskAwardId = stTaskPBConfigUnit.task_award_id_3(); //or 9999|award class set string 
				    unsigned int iAwardItemId = atoi(strTaskAwardId.c_str());
				    if( iAwardItemId==TASK_AWARD_SETCLASS )
				    {
					    ctAward3.m_strItemSet = string(strTaskAwardId.c_str(), 5, strTaskAwardId.length()-5 );
				    }
				    ctAward3.m_iAwardItemId = iAwardItemId;

				    stConfigData._astTaskAward.AddOneItem( ctAward3 );

                    if( stTaskPBConfigUnit.award_type_4() != 0 )
                    {
                        CTaskAward ctAward4;
                        ctAward4.m_iAwardType = stTaskPBConfigUnit.award_type_4();
                        ctAward4.m_iAwardData = stTaskPBConfigUnit.award_num_4();
                        string strTaskAwardId = stTaskPBConfigUnit.task_award_id_4(); //or 9999|award class set string 
                        unsigned int iAwardItemId = atoi(strTaskAwardId.c_str());
                        if( iAwardItemId==TASK_AWARD_SETCLASS )
                        {
                            ctAward4.m_strItemSet = string(strTaskAwardId.c_str(), 5, strTaskAwardId.length()-5 );
                        }
                        ctAward4.m_iAwardItemId = iAwardItemId;

                        stConfigData._astTaskAward.AddOneItem( ctAward4 );
                    }
			    }
		    }
	    }

        //副本查找类型
        stConfigData._usInstanceID = stTaskPBConfigUnit.ins_id();

        stConfigData._bHasConfig = true;
        iRet = AddConfig(stConfigData);
        if (RET_OK != iRet)
        {
            CT_ERROR(("%d", iRet));
            return iRet;
        }
        
    }

    //悬赏令任务
    for (int i = 0; i < stTaskPBConfig.reward_task_rows_size(); ++i)
    {
        const pb_cfg_task_pb_cfg_reward_task_unit& stPBConfigUnit 
            = stTaskPBConfig.reward_task_rows(i);

        CRewardTaskConfigData stConfigData;
        stConfigData._ucRewardType = stPBConfigUnit.reward_type();
        stConfigData._iPublishLevel = stPBConfigUnit.open_level();
        stConfigData._usPublishMaterialID = stPBConfigUnit.material_id();
        stConfigData._iExpBonusPara = stPBConfigUnit.exp_bonus();
        stConfigData._iSilverBonusPara = stPBConfigUnit.silver_bonus();
        stConfigData._iTaskID = stPBConfigUnit.task_id();

        iRet = _stRewardTaskConfig.AddConfig(stConfigData);
        CHECK_RETURN(iRet);
    }

    return 0;
}

int CTaskMgr::AddConfig(CTaskConfigData& stConfigData)
{
    CT_TRACE(("添加任务配置："));
    stConfigData._stTaskID.DumpTaskID();
    CT_TRACE(("是否可以直接领取 %d, 激活条件数 %d, 完成条件数 %d, 后续任务数 %d", 
        stConfigData.IsDirectAccept(), stConfigData._astOpenConds.Size(), stConfigData._astFinishConds.Size(),
        stConfigData._astFollowTasks.Size()));

    return _stTaskConfig.AddConfig(stConfigData);
}

int CTaskMgr::GetTaskIDStruct(int iTaskID, CTaskID& stTaskID)
{
    stTaskID._uiTaskID = iTaskID % TASK_CONFIG_ID_MOD;
    stTaskID._uiBranchID = iTaskID / TASK_CONFIG_ID_MOD;
    return 0;
}

int CTaskMgr::GetTaskConfig(CTaskID& stTaskID, CTaskConfigData& stTaskConfigData)
{
    return _stTaskConfig.GetConfig(stTaskID, stTaskConfigData);
}

int CTaskMgr::AcceptTask(CTaskID& stTaskID, CUserTask& stUserTask)
{
    int iRet = 0;

    CT_TRACE(("开始接受任务: "));
    stTaskID.DumpTaskID();

    //检查失效任务
    CheckTaskExpire(stUserTask);

    CTaskConfigData stConfigData;
    iRet = _stTaskConfig.GetConfig(stTaskID, stConfigData);
    CHECK_RETURN(iRet);

    //检查任务是否已满
    if (stUserTask.IsFull())
    {
        return ERROR_TASK_FULL;
    }

    //检查是否需要激活任务
    if (stConfigData.NeedOpen() && !stUserTask.IsCanAcceptTask(stTaskID))
    {
        return ERROR_TASK_CAN_NOT_ACCEPT_NOT_OPEN;
    }

    //检查任务是否已经完成
    if (!stConfigData.IsCyclicTask() && stUserTask._stTaskStatus.IsFinished(stTaskID))
    {
        stUserTask.CheckTaskHasFinished(stTaskID);      //删掉这个任务
        return ERROR_TASK_CAN_NOT_ACCEPT_FINISHED;
    }

    //检查任务是否已经接受
    if (stUserTask.IsValidTask(stTaskID))
    {
        return ERROR_TASK_CAN_NOT_ACCEPT_VALID;
    }

    //去掉可接相应的已激活任务
    if (stConfigData.NeedOpen()>=0)
    {
        iRet = stUserTask.CleanOpenTask(stTaskID);
        CHECK_RETURN(iRet);
    }

    //添加任务
    CValidTask stValidTask(stTaskID);
    if (stTaskID.IsLessonTask()
        || stTaskID.IsRewardTask())  //上课作业、悬赏令任务需要自动生成任务目标
    {
        int iIndex = CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash.HashFind(stUserTask._uiGID);
        if (iIndex < 0)
        {
            CT_ERROR(("%u", stUserTask._uiGID));
            return RET_NO_USER;
        }
        CPlayerOnlineData& stPlayerOnlineData = CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash[iIndex];

        for (int i = 0; i < stConfigData._astFinishConds.Size(); ++i)
        {
            CTaskTargetStat stStat;
            stStat._bIsReachCond = false;
            stStat._stTaskID = stTaskID;
            stStat._stCond = stConfigData._astFinishConds[i];
            stStat._stNowStat._ucCond = stStat._stCond._ucCond;

            switch (stStat._stCond._ucCond)
            {
            case CTaskCond::TASK_ENEMY_KILL:
                {
                    unsigned int uiMonsterID = 0;
                    unsigned short usDestInsID = 0;
                    iRet = CMainCtrl::m_pstMain->m_stInstanceMgr.GetSuitableMonster(stPlayerOnlineData._stUserInstance, uiMonsterID, usDestInsID);
                    if (iRet != RET_OK || uiMonsterID == 0)
                    {
                        uiMonsterID = stStat._stCond._iCondData1;
                        usDestInsID = stConfigData._usInstanceID % 10000;
                    }

                    stStat._stCond._iCondData1 = uiMonsterID;                                   
                    stStat._stCond._iCondData2 = stConfigData._astFinishConds[i]._iCondData2;   //怪物数量

                    stStat._stNowStat._iCondData1 = stStat._stCond._iCondData1;
                    stStat._stNowStat._iCondData2 = 0;

                    stStat._iData1 = 10000 + usDestInsID;
                }
                break;
            case CTaskCond::TASK_GET_ITEM:
                {
                    unsigned char ucItemType = stStat._stCond._iCondData1 / ITEM_CONFIG_ID_MOD;
                    unsigned short usItemConfigID = 0;
                    unsigned short usItemInInsID = 0;
                    
                    iRet = CMainCtrl::m_pstMain->m_stInstanceMgr.GetSuitableItem(stPlayerOnlineData._stUserInstance, ucItemType, usItemConfigID, usItemInInsID);
                    if (iRet != RET_OK || usItemConfigID == 0)
                    {
                        usItemInInsID = stConfigData._usInstanceID;
                        usItemConfigID = stStat._stCond._iCondData1 % ITEM_CONFIG_ID_MOD;
                    }
                                
                    stStat._stCond._iCondData1 = ucItemType * ITEM_CONFIG_ID_MOD + usItemConfigID;
                    stStat._stNowStat._iCondData1 = stStat._stCond._iCondData1;
                    stStat._stCond._iCondData2 = stConfigData._astFinishConds[i]._iCondData2;
                    stStat._stNowStat._iCondData2 = 0;

                    stStat._iData1 = 10000 + usItemInInsID;
                }
                break;
            case CTaskCond::TASK_DO_SOME_OPT:
                {                    
                    stStat._stNowStat._iCondData1 = stStat._stCond._iCondData1;
                    stStat._stNowStat._iCondData2 = 0;
                }
                break;
             default:
                return ERROR_TASK_TRIGGER_COND_TYPE;
            }
           
            stValidTask._astTargetStats.AddOneItem(stStat);
        }
    }
    else
    {
        for (int i = 0; i < stConfigData._astFinishConds.Size(); ++i)
        {
            CTaskTargetStat stStat;
            stStat._bIsReachCond = false;
            stStat._stTaskID = stTaskID;
            stStat._stCond = stConfigData._astFinishConds[i];
            stStat._stNowStat._ucCond = stStat._stCond._ucCond;
            stStat._stNowStat._iCondData1 = stStat._stCond._iCondData1;
            stStat._stNowStat._iCondData2 = 0;

            stValidTask._astTargetStats.AddOneItem(stStat);
        }
    }

    if (stConfigData._astFinishConds.Size() > 0)
    {
        stValidTask._ucTaskStat = CValidTask::TASK_STAT_NORMAIL;
    }
    else
    {
        stValidTask._ucTaskStat = CValidTask::TASK_STAT_FINISH;
    }

    iRet = stUserTask.AddValidTaskData(stValidTask);
    CHECK_RETURN(iRet);

    //使用当前的角色数据触发一下触发器，确保新添加的任务保持最新的任务状态
    iRet = UserDataTrigger(stUserTask);
    CHECK_RETURN(iRet);

    //任务可能会打开副本，所以任务提交的时候刷新副本列表
    CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(stUserTask.GetUserGid(), NOTIFY_INSTANCE_INFO);

    int iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(stUserTask.GetUserGid());
    if (iIndex >= 0)
    {
        stUserTask.GetData(CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex]._stUserTaskData);

        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_BASE_INFO;
        stKey.m_u64ID = stUserTask.GetUserGid();

        CMainCtrl::m_pstMain->UpdateData(stKey, CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex], VOP_UPDATE);
    }
    
    return 0;
}

int CTaskMgr::CommitTask(CTaskID& stTaskID, CUserTask& stUserTask)
{
    int iRet = 0;

    CT_TRACE(("提交任务:"));

    CTaskConfigData stConfigData;
    iRet = _stTaskConfig.GetConfig(stTaskID, stConfigData);
    CHECK_RETURN(iRet);

    iRet = stUserTask.CommitTask(stTaskID);
    CHECK_RETURN(iRet);

    for (int i = 0; i < stConfigData._astFollowTasks.Size(); ++i)
    {
        CT_TRACE(("打开后续任务 %d", i));

        CTaskConfigData stFollowTaskConfigData;
        iRet = _stTaskConfig.GetConfig(stConfigData._astFollowTasks[i], stFollowTaskConfigData);
        CHECK_RETURN(iRet);

        if (!stFollowTaskConfigData.NeedOpen())
        {
            iRet = AcceptTask(stFollowTaskConfigData._stTaskID, stUserTask);
            CHECK_RETURN(iRet);
        }
        else
        {
            iRet = WaitForOpenTask(stFollowTaskConfigData._stTaskID, stUserTask);
            CHECK_RETURN(iRet);
        }
    }

    iRet = UserDataTrigger(stUserTask);
    CHECK_RETURN(iRet);

    //触发任务完成事件
    TriggerTaskFinish(stUserTask, stTaskID);

    //trigger task award
    TriggerTaskAward(stUserTask, stConfigData);

    return 0;
}

int CTaskMgr::WaitForOpenTask(CTaskID& stTaskID, CUserTask& stUserTask)
{
    int iRet = 0;

    CT_TRACE(("将任务加入等待激活列表"));
    stTaskID.DumpTaskID();

    CTaskConfigData stConfigData;
    iRet = _stTaskConfig.GetConfig(stTaskID, stConfigData);
    CHECK_RETURN(iRet);

    CTaskWaitForOpen stWaitForOpen;
    stWaitForOpen._stTaskID = stTaskID;
    stWaitForOpen._bDirectAccept = stConfigData.IsDirectAccept();

    for (int i = 0; i < stConfigData._astOpenConds.Size(); ++i)
    {
        CTaskTargetStat stStat;
        stStat._bIsReachCond = false;
        stStat._stTaskID = stTaskID;
        stStat._stCond = stConfigData._astOpenConds[i];
        stStat._stNowStat._ucCond = stStat._stCond._ucCond;
        stStat._stNowStat._iCondData1 = stStat._stCond._iCondData1;
        stStat._stNowStat._iCondData2 = 0;

        stWaitForOpen._astTargetStats.AddOneItem(stStat);
    }

    iRet = stUserTask.AddWaitForOpenData(stWaitForOpen);
    CHECK_RETURN(iRet);

    return 0;
}

int CTaskMgr::UserDataTrigger(CUserTask& stUserTask)
{
    int iRet = 0;
    unsigned int uiGID = stUserTask.GetUserGid();
    CMainCtrl* pstMainctrl = CMainCtrl::m_pstMain;

    CT_TRACE(("使用用户数据触发:"));

    iRet = TriggerLevelUp(stUserTask, _stUserDataInf.GetLevel(uiGID));
    CHECK_RETURN(iRet);
    CT_TRACE(("触发升级事件: 当前等级 %d", _stUserDataInf.GetLevel(uiGID)));

    //用主线任务当前状态再触发一下
    CTaskID stMainTaskID;
    stMainTaskID._uiTaskID = stUserTask._stTaskStatus._uiMainTaskStatus;
    stMainTaskID._uiBranchID = 0;
    iRet = TriggerTaskFinish(stUserTask, stMainTaskID);

    int iIndex = pstMainctrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_WARNING(("%u", uiGID));
        return RET_OK;
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainctrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._sRoleName.GetDataLen() != 0)
    {
        TriggerDoSomeOpt(stUserTask, TASK_OPT_ID_102, 1);
    }

    //主线副本触发
    int iTaskInstanceId = CONST_TASK_INSTANCE_ID_MOD * CInstanceConfigData::INSTANCE_TYPE_MAIN + stPlayerBaseInfo._stInstanceData._stHasFinishedInstanceData._usMainInstanceData;
    TriggerFinishInstance(stUserTask, iTaskInstanceId, 1);

    //宠物等级触发
    TriggerPetLevelUp(stUserTask, stPlayerBaseInfo._stUserPetData._iPetLevel);

    //用户操作触发
    if (stPlayerBaseInfo._ucIsInited == 1 && stUserTask.HasDoSomeOptTask())
    {
        int iIndex = -1;

        iIndex = pstMainctrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
        if (iIndex < 0)
        {
            CT_WARNING(("%u", uiGID));
            return RET_OK;
        }
        CPlayerDetailInfo& stPlayerDetailInfo = pstMainctrl->m_stPlayerDetailInfoHash[iIndex];
        
        //伙伴招募
        for (int i = 0; i < stPlayerDetailInfo._stUserPartner._astActData.Size(); ++i)
        {
            TriggerDoSomeOpt(stUserTask, 109000 + stPlayerDetailInfo._stUserPartner._astActData[i]._shResID, 1);
        }

        //上阵
        if (stPlayerDetailInfo._stPlayerMatrix._chMainMatrix >= 0)
        {
            CMatrixList& stMatrixList = stPlayerDetailInfo._stPlayerMatrix._astMatrixData[stPlayerDetailInfo._stPlayerMatrix._chMainMatrix];
            for (int i = 0; i < stMatrixList._astMatrixList.Size(); ++i)
            {
                if (GAME_OBJ_TYPE_PARTNER == stMatrixList._astMatrixList[i]._chType)
                {
                    TriggerDoSomeOpt(stUserTask, 110000 + stMatrixList._astMatrixList[i]._uiID, 1);
                }
            }
        }
        
        //家族
        if (stPlayerDetailInfo._stUserClan._uiClanId > 0)
        {
            TriggerDoSomeOpt(stUserTask, TASK_OPT_ID_114, 1); //加入或创建一个家族
        }
        
        //伙伴升级
        for (int i = 0; i < stPlayerDetailInfo._stUserPartner._astActData.Size(); ++i)
        {
            TriggerDoSomeOpt(stUserTask, (TASK_OPT_ID_116 * 1000 + stPlayerDetailInfo._stUserPartner._astActData[i]._shResID) * 1000 + stPlayerDetailInfo._stUserPartner._astActData[i]._shLevel, 1); //将伙伴X等级提升至Y级
            TriggerDoSomeOpt(stUserTask, TASK_OPT_ID_124 * 1000 + stPlayerDetailInfo._stUserPartner._astActData[i]._shLevel, 1); //将伙伴等级提升至X级
        }

        {
            int iIndex = CMainCtrl::m_pstMain->m_stPlayerSnsDetailInfoHash.HashFind(uiGID);
            if (iIndex >= 0)
            {
                //触发最高强化等级
                TriggerDoSomeOpt(stUserTask, TASK_OPT_ID_113 * 1000 + CMainCtrl::m_pstMain->m_stPlayerSnsDetailInfoHash[iIndex]._stMyInfo._stPlayerStatic._iMaxEquipStrengthLevel, 1);
            }
        }
    }
    
    return 0;
}

int CTaskMgr::CheckTaskNeedToAccept(CUserTask& stUserTask)
{
    int iRet = 0;
    if (!stUserTask.HasTaskNeedToAccept())
    {
        return 0;
    }

    CT_TRACE(("有任务需要被自动打开:"));

    CTLib::CTArray<CTaskID, MAX_NEED_TO_ACCEPT>& astTaskNeedToAccept = 
            stUserTask.GetTaskNeedAcceptList();

    for (int i = 0; i < astTaskNeedToAccept.Size(); ++i)
    {
        iRet = AcceptTask(astTaskNeedToAccept[i], stUserTask);
        CHECK_RETURN(iRet);
    }

    stUserTask.CleanTaskNeedAcceptList();

    return 0;
}

int CTaskMgr::TriggerLevelUp(CUserTask& stUserTask, int iNowLevel)
{
    int iRet = 0;

    CT_TRACE(("触发事件开始，由于等级变化而触发，当前等级 %d", iNowLevel));

    iRet = stUserTask.TriggerLevelUp(iNowLevel);
    CHECK_RETURN(iRet);

    iRet = CheckTaskNeedToAccept(stUserTask);
    CHECK_RETURN(iRet);

    return 0;
}

int CTaskMgr::TriggerPetLevelUp(CUserTask& stUserTask, int iNowPetLevel)
{
    int iRet = 0;

    CT_TRACE(("触发事件开始，由于宠物升级，当前等级 %d", iNowPetLevel));

    iRet = stUserTask.TriggerPetLevelUp(iNowPetLevel);
    CHECK_RETURN(iRet);

    iRet = CheckTaskNeedToAccept(stUserTask);
    CHECK_RETURN(iRet);

    return 0;
}

int CTaskMgr::TriggerTaskFinish(CUserTask& stUserTask, CTaskID& stTaskID)
{
    int iRet = 0;

    CT_TRACE(("触发事件开始，由于完成任务触发"));

    iRet = stUserTask.TriggerTaskFinish(stTaskID);
    CHECK_RETURN(iRet);

    //检查任务
    iRet = CheckTaskNeedToAccept(stUserTask);
    CHECK_RETURN(iRet);

    return 0;
}

int CTaskMgr::TriggerBossConquer(CUserTask& stUserTask, int iBossID, int iCount)
{
    int iRet = 0;

    iRet = stUserTask.TriggerConquerBoss(iBossID, iCount);
    CHECK_RETURN(iRet);

    iRet = CheckTaskNeedToAccept(stUserTask);
    CHECK_RETURN(iRet);

    return 0;
}

int CTaskMgr::TriggerKillEnemy(CUserTask& stUserTask, int iEnemyID, int iCount)
{
    int iRet = 0;

    iRet = stUserTask.TriggerKillEnemy(iEnemyID, iCount);
    CHECK_RETURN(iRet);

    iRet = CheckTaskNeedToAccept(stUserTask);
    CHECK_RETURN(iRet);

    return 0;
}

int CTaskMgr::TriggerDoSomeOpt(CUserTask& stUserTask, int iOptID, int iCount)
{
    int iRet = 0;

    iRet = stUserTask.TriggerDoSomeOpt(iOptID, iCount);
    CHECK_RETURN(iRet);

    iRet = CheckTaskNeedToAccept(stUserTask);
    CHECK_RETURN(iRet);

    return 0;
}

int CTaskMgr::TriggerUseItem(CUserTask& stUserTask, unsigned char ucItemType, unsigned short usItemID, int iCount)
{
    int iRet = 0;

    iRet = stUserTask.TriggerUseItem(ucItemType, usItemID, iCount);
    CHECK_RETURN(iRet);

    iRet = CheckTaskNeedToAccept(stUserTask);
    CHECK_RETURN(iRet);

    return 0;
}

int CTaskMgr::TriggerGetItem(CUserTask& stUserTask, unsigned char ucItemType, unsigned short usItemID, int iCount)
{
    int iRet = 0;

    iRet = stUserTask.TriggerGetItem(ucItemType, usItemID, iCount);
    CHECK_RETURN(iRet);

    iRet = CheckTaskNeedToAccept(stUserTask);
    CHECK_RETURN(iRet);

    return 0;
}

int CTaskMgr::TriggerFinishInstance(CUserTask& stUserTask, int iInstanceID, int iCount)
{
    int iRet = 0;

    iRet = stUserTask.TriggerFinishInstance(iInstanceID, iCount);
    CHECK_RETURN(iRet);

    iRet = CheckTaskNeedToAccept(stUserTask);
    CHECK_RETURN(iRet);

    return 0;
}

bool CTaskMgr::IsTaskFinished(CUserTask& stUserTask, CTaskID& stTaskID)
{
    return stUserTask.IsTaskFinished(stTaskID);
}

bool CTaskMgr::IsTaskAccepted(CUserTask& stUserTask, CTaskID& stTaskID)
{
    return stUserTask.IsValidTask(stTaskID);
}

int CTaskMgr::TriggerTaskAward(CUserTask& stUserTask, CTaskConfigData& curTaskCfgData)
{
	int iRet = 0;
	CDropItem stDropItem;

	iRet = stUserTask.GetTaskAwardItems(curTaskCfgData, stDropItem);
	if (iRet != RET_OK)
	{
	    CT_WARNING(("CTaskMgr::TriggerTaskAward:get award items fail-%d", iRet));
	}

	//assign award items to user
    stDropItem.SetOssModule(OSS_MODULE_TASK);
	iRet = CMainCtrl::m_pstMain->m_stItemMgr.DropItem(NULL, stUserTask.GetUserGid(), stDropItem);

	return iRet;
}


int CTaskMgr::GMSetTaskFinished(int iTaskId, CUserTask& stUserTask)
{
    if( iTaskId<=0 )
    {
        CT_TRACE(("GM set task finish:arguments error%d", iTaskId));
        return -1;
    }

    int iRet = 0;
    CTaskID stTaskID;
    stTaskID._uiBranchID = (unsigned int)iTaskId / TASK_CONFIG_ID_MOD;
    stTaskID._uiTaskID = (unsigned int)iTaskId % TASK_CONFIG_ID_MOD;

    stUserTask.GMSetTaskFinished( stTaskID );

    CTaskConfigData stConfigData;
    iRet = _stTaskConfig.GetConfig(stTaskID, stConfigData);
    CHECK_RETURN(iRet);

    for (int i = 0; i < stConfigData._astFollowTasks.Size(); ++i)
    {
        CT_TRACE(("打开后续任务 %d", i));

        CTaskConfigData stFollowTaskConfigData;
        iRet = _stTaskConfig.GetConfig(stConfigData._astFollowTasks[i], stFollowTaskConfigData);
        CHECK_RETURN(iRet);
        iRet = this->GMAddFollowTasks( stFollowTaskConfigData, stUserTask );

        /* if (!stFollowTaskConfigData.NeedOpen())
        {
            iRet = AcceptTask(stFollowTaskConfigData._stTaskID, stUserTask);
            CHECK_RETURN(iRet);
        }
        else
        {
            iRet = WaitForOpenTask(stFollowTaskConfigData._stTaskID, stUserTask);
            CHECK_RETURN(iRet);
        } */
    }

    iRet = stUserTask.UpdateTaskList2Front();

    return iRet;
}

int CTaskMgr::GMAddFollowTasks(CTaskConfigData& stFollowTaskConfigData, CUserTask& stUserTask)
{
    int iRet = 0;        
    //Add follow tasks
    CValidTask stValidTask(stFollowTaskConfigData._stTaskID);
    for (int i = 0; i < stFollowTaskConfigData._astFinishConds.Size(); ++i)
    {
        CTaskTargetStat stStat;
        stStat._bIsReachCond = false;
        stStat._stTaskID = stFollowTaskConfigData._stTaskID;
        stStat._stCond = stFollowTaskConfigData._astFinishConds[i];
        stStat._stNowStat._ucCond = stStat._stCond._ucCond;
        stStat._stNowStat._iCondData1 = stStat._stCond._iCondData1;
        stStat._stNowStat._iCondData2 = 0;

        stValidTask._astTargetStats.AddOneItem(stStat);
    }

    if (stFollowTaskConfigData._astFinishConds.Size() > 0)
    {
        stValidTask._ucTaskStat = CValidTask::TASK_STAT_NORMAIL;
    }
    else
    {
        stValidTask._ucTaskStat = CValidTask::TASK_STAT_FINISH;
    }

    iRet = stUserTask.AddValidTaskData(stValidTask);
    CHECK_RETURN(iRet);

    return 0;
}

void CTaskMgr::CheckTaskExpire(CUserTask& stUserTask)
{
    int iNowTime = CMainCtrl::m_pstMain->m_iNow;
    CTLib::CTArray<CTaskID, MAX_VALID_TASK> _astDelTaskIDs;

    //时间失效
    for (int i = 0; i < stUserTask._astValidTasks.Size(); ++i)
    {
        CValidTask& stValidTask = stUserTask._astValidTasks[i];
        if (stValidTask._iTaskEndTime != 0 && stValidTask._iTaskEndTime < iNowTime)
        {
            _astDelTaskIDs.AddOneItem(stValidTask._stTaskID);
        }
    }

    //删除任务
    for (int i = 0; i < _astDelTaskIDs.Size(); ++i)
    {
        stUserTask.DelValidTaskData(_astDelTaskIDs[i]);
    }
}

int CTaskMgr::SetTaskTime(CUserTask& stUserTask, CTaskID& stTaskID, int iEndTime)
{
    for (int i = 0; i < stUserTask._astValidTasks.Size(); ++i)
    {
        if (stUserTask._astValidTasks[i]._stTaskID == stTaskID)
        {   
            stUserTask._astValidTasks[i]._iTaskEndTime = iEndTime;
            break;
        }
    }
    
    return 0;
}

int CTaskMgr::GetTaskInfo(CUserTask& stUserTask, CTaskID& stTaskID, MsgOneTask& stAnsInfo)
{
    unsigned int uiGID = stUserTask._uiGID;
    for (int i = 0; i < stUserTask._astValidTasks.Size(); ++i)
    {
        if (stTaskID == stUserTask._astValidTasks[i]._stTaskID)
        {
            CValidTask& stValidTask = stUserTask._astValidTasks[i];
            stAnsInfo.set_task_id(stValidTask._stTaskID._uiBranchID * TASK_CONFIG_ID_MOD + stValidTask._stTaskID._uiTaskID);
            stAnsInfo.set_task_stat(stValidTask._ucTaskStat);
            
            for (int j = 0; j < stValidTask._astTargetStats.Size(); ++j)
            {
                CTaskTargetStat& stTaskTargetStat = stValidTask._astTargetStats[j];
                MsgTaskTarget* pstMsgTaskTarget = stAnsInfo.add_task_targets();
                pstMsgTaskTarget->set_is_reach_cond(stTaskTargetStat._bIsReachCond ? 1 : 0);
                pstMsgTaskTarget->set_cond_type(stTaskTargetStat._stCond._ucCond);
                pstMsgTaskTarget->set_data1(stTaskTargetStat._stCond._iCondData1);
                pstMsgTaskTarget->set_finish_stat(stTaskTargetStat._stCond._iCondData2);
                pstMsgTaskTarget->set_now_stat(stTaskTargetStat._stNowStat._iCondData2);

                CTaskTargetStatData stTargetStatData;
                stTaskTargetStat.GetData(stTargetStatData);
                GetTargetDetailInfo(uiGID, *pstMsgTaskTarget, stTargetStatData);
            }
            
            break;
        }
    }
    
    return 0;
}

void CTaskMgr::GetTaskList(CUserTask& stUserTask, MsgAnsGetTaskList& stTaskListAns)
{
    int iRet = 0;

    CheckTaskExpire(stUserTask);

    int iNowTime = CMainCtrl::m_pstMain->m_iNow;
    CUserTaskData stUserTaskData;
    iRet = stUserTask.GetData(stUserTaskData);
    if (iRet != RET_OK)
    {
        CT_WARNING(("%u", stUserTask.GetUserGid()));
        return;
    }

    //传递已激活的任务
    for (int i = 0; i < stUserTaskData._astOpenTaskIDs.Size(); ++i)
    {
        stTaskListAns.add_task_can_get(stUserTaskData._astOpenTaskIDs[i]._uiBranchID * TASK_CONFIG_ID_MOD 
            + stUserTaskData._astOpenTaskIDs[i]._uiTaskID);
    }

    //传递进行中的任务
    for (int i = 0; i < stUserTaskData._astValidTasks.Size(); ++i)
    {
        if (stUserTaskData._astValidTasks[i]._iTaskEndTime != 0
            && stUserTaskData._astValidTasks[i]._iTaskEndTime < iNowTime)
        {
            continue;
        }
        
        MsgOneTask* pstOneTask = stTaskListAns.add_tasks();
        pstOneTask->set_task_id(stUserTaskData._astValidTasks[i]._stTaskID._uiBranchID * TASK_CONFIG_ID_MOD 
            + stUserTaskData._astValidTasks[i]._stTaskID._uiTaskID);
        pstOneTask->set_task_stat(stUserTaskData._astValidTasks[i]._ucIsFinished);
        pstOneTask->set_expire_time(stUserTaskData._astValidTasks[i]._iTaskEndTime);

        for (int j = 0; j < stUserTaskData._astValidTasks[i]._astTargetStats.Size(); ++j)
        {
            MsgTaskTarget* pstTaskTarget = pstOneTask->add_task_targets(); 

            CTaskTargetStatData& stTargetStatData = stUserTaskData._astValidTasks[i]._astTargetStats[j];

            pstTaskTarget->set_is_reach_cond(stTargetStatData._ucIsReachCond);
            pstTaskTarget->set_cond_type(stTargetStatData._stCond._ucCond);
            pstTaskTarget->set_data1(stTargetStatData._stCond._iCondData1);
            pstTaskTarget->set_finish_stat(stTargetStatData._stCond._iCondData2);
            pstTaskTarget->set_now_stat(stTargetStatData._stNowStat._iCondData2);
            
            /* set the item's instance id */
            GetTargetDetailInfo(stUserTask.GetUserGid(), *pstTaskTarget, stTargetStatData);
        }
    }

    //后续任务
    if (stUserTaskData._astOpenTaskIDs.Size() == 0
        && stUserTaskData._astValidTasks.Size() == 0)
    {
        for (int i = 0; i < stUserTaskData._astWaitForOpenTasks.Size(); ++i)
        {
            if (stUserTaskData._astWaitForOpenTasks[i]._stTaskID._uiBranchID != 0) //跳过非主线任务
            {
                continue;
            }

            MsgOneTask* pstOneTask = stTaskListAns.mutable_next_task();
            pstOneTask->set_task_id(stUserTaskData._astWaitForOpenTasks[i]._stTaskID._uiBranchID * TASK_CONFIG_ID_MOD 
                + stUserTaskData._astWaitForOpenTasks[i]._stTaskID._uiTaskID);

            for (int j = 0; j < stUserTaskData._astWaitForOpenTasks[i]._astTargetStats.Size(); ++j)
            {
                MsgTaskTarget* pstTaskTarget = pstOneTask->add_task_targets(); 

                CTaskTargetStatData& stTargetStatData = stUserTaskData._astWaitForOpenTasks[i]._astTargetStats[j];

                pstTaskTarget->set_is_reach_cond(stTargetStatData._ucIsReachCond);
                pstTaskTarget->set_cond_type(stTargetStatData._stCond._ucCond);
                pstTaskTarget->set_data1(stTargetStatData._stCond._iCondData1);
                pstTaskTarget->set_finish_stat(stTargetStatData._stCond._iCondData2);
                pstTaskTarget->set_now_stat(stTargetStatData._stNowStat._iCondData2);

                /* set the item's instance id */
                GetTargetDetailInfo(stUserTask.GetUserGid(), *pstTaskTarget, stTargetStatData);
            }

            break;
        }

    }
    
}

int CTaskMgr::GetTargetDetailInfo(unsigned int uiGID, MsgTaskTarget& stTaskTarget, CTaskTargetStatData& stTargetStatData)
{
    int iRet = 0;
    //CMainCtrl* pstMainCtrl = CMainCtrl::m_pstMain;

    CTaskConfigData stConfigData;
    CTaskID stTaskID;
    stTaskID.Init(stTargetStatData._stTaskID);

    iRet = _stTaskConfig.GetConfig(stTaskID, stConfigData);
    CHECK_RETURN(iRet);

    switch( stTargetStatData._stCond._ucCond )
    {
    case CTaskCond::TASK_USE_ITEM:
    case CTaskCond::TASK_GET_ITEM:
    case CTaskCond::TASK_GET_AND_COMMIT_ITEM:
        {
            /* 暂时用任务配置配的INS ID
            if( stTargetStatData._stCond._iInstanceMapId == 0 )
            {
                int iItemType = stTargetStatData._stCond._iCondData1/CONST_TASK_ITEM_TYPE_MOD;
                int iItemId = stTargetStatData._stCond._iCondData1%CONST_TASK_ITEM_TYPE_MOD;

                int iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
                if (iIndex < 0)
                {
                    return RET_SYS_ERROR;
                }
                CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

                CInstanceId stDropInstanceId;
                iRet = pstMainCtrl->m_stInstanceMgr.GetDropInstanceID(iItemType, iItemId,
                    stPlayerOnlineData._stUserInstance._stInstanceData._stHasOpenedInstanceData, stDropInstanceId);
                if(iRet == RET_OK)
                {
                    stTargetStatData._stCond._iInstanceMapId = stDropInstanceId._ucInstanceType * CONST_TASK_INSTANCE_ID_MOD + stDropInstanceId._usInstanceID;
                }
            }
            stTaskTarget.set_map_id( stTargetStatData._stCond._iInstanceMapId );
            */

            if (stTaskID.IsLessonTask())
            {
                stTaskTarget.set_map_id(stTargetStatData._iData1);
            }
            else
            {
                stTaskTarget.set_map_id(stConfigData._usInstanceID);
            }
        }
        break;
    case CTaskCond::TASK_FINISH_STAGE:
        {
            stTaskTarget.set_map_id (stTargetStatData._stCond._iCondData1);
        }
        break;
    case CTaskCond::TASK_ENEMY_KILL:
        {
            if (stTaskID.IsLessonTask() || stTaskID.IsRewardTask())
            {
                stTaskTarget.set_map_id(stTargetStatData._iData1);
            }
            else
            {
                stTaskTarget.set_map_id(stConfigData._usInstanceID);
            }
        }
        break;
    case CTaskCond::TASK_NCP_TALK:
        {
            stTaskTarget.set_npc_id(stConfigData._iCommitNPC);
        }
        break;
    default:
        {
            stTaskTarget.set_map_id(0);
        }
        break;
    }
    return iRet;
}

void CTaskMgr::GetRewardTaskList(unsigned int uiGID, MsgAnsAwardTask& stAns)
{
    int iRet = 0;
    for (int i = 0; i < _stRewardTaskList.Size(); ++i)
    {
        CRewardTaskListData& stRewardTask = _stRewardTaskList[i];
        if (stRewardTask._uiPublishGID == uiGID)
        {
            continue;
        }

        //已经过期
        if ((stRewardTask._iPublishTime + MAX_REWARD_TASK_VALID_SEC) < CMainCtrl::m_pstMain->m_iNow)
        {
            continue;
        }

        CRewardTaskConfigData stConfigData;
        iRet = _stRewardTaskConfig.GetConfig(stRewardTask._ucTaskType, stConfigData);
        if (iRet)
        {
            CT_WARNING(("%d", stRewardTask._ucTaskType));
            continue;
        }

        CTaskID stRewardTaskID;
        stRewardTaskID._uiBranchID = 998;
        stRewardTaskID._uiTaskID = stConfigData._iTaskID;
        CTaskConfigData stRewardTaskConfigData;
        iRet = _stTaskConfig.GetConfig(stRewardTaskID, stRewardTaskConfigData);
        if (iRet)
        {
            CT_WARNING(("%d", stRewardTaskID._uiTaskID));
            continue;
        }

        int iSilverBonus = 0;
        int iExpBonus = 0;
        for (int i = 0; i < stRewardTaskConfigData._astTaskAward.Size(); ++i)
        {
            if (stRewardTaskConfigData._astTaskAward[i].m_iAwardType == ITEM_TYPE_LEVEL_SILVER)
            {
                iSilverBonus = stRewardTaskConfigData._astTaskAward[i].m_iAwardData;
            }
            else if (stRewardTaskConfigData._astTaskAward[i].m_iAwardType == ITEM_TYPE_LEVEL_EXP)
            {
                iExpBonus = stRewardTaskConfigData._astTaskAward[i].m_iAwardData;
            }
        }
        
        MsgAwardTaskDetail* pstMsgAwardTaskDetail = stAns.add_task_list();
        pstMsgAwardTaskDetail->set_task_type(stRewardTask._ucTaskType);
        pstMsgAwardTaskDetail->set_publish_gid(stRewardTask._uiPublishGID);
        pstMsgAwardTaskDetail->set_publish_name(CMainCtrl::m_pstMain->m_stRoleMgr.GetRoleName(stRewardTask._uiPublishGID));
        pstMsgAwardTaskDetail->set_publish_time(stRewardTask._iPublishTime);

        CDropItemData stDropItemData;

        stDropItemData.Clear();
        CMainCtrl::m_pstMain->m_stItemMgr.GetLevelItem(uiGID, ITEM_TYPE_LEVEL_SILVER, 0, iSilverBonus, stDropItemData);
        pstMsgAwardTaskDetail->set_bonus_silver(stDropItemData._iItemCount);

        stDropItemData.Clear();
        CMainCtrl::m_pstMain->m_stItemMgr.GetLevelItem(uiGID, ITEM_TYPE_LEVEL_EXP, 0, iExpBonus, stDropItemData);
        pstMsgAwardTaskDetail->set_bonus_exp(stDropItemData._iItemCount);
    }
}

void CTaskMgr::GetRewardTaskInfo(CRewardTask& stRewardTask, unsigned int uiGID, MsgAnsAwardTask& stAns)
{
    int iNowTime = CMainCtrl::m_pstMain->m_iNow;

    stAns.set_can_pub_count(MAX_REWARD_TASK_CAN_PUBLISH_COUNT - stRewardTask._stHasPublishCount.Get(iNowTime));
    stAns.set_can_get_count(MAX_REWARD_TASK_CAN_ACCEPT_COUNT - stRewardTask._stHasAcceptCount.Get(iNowTime));
}

void CTaskMgr::GetMyRewardTaskList(CRewardTask& stRewardTask, unsigned int uiGID, MsgAnsAwardTask& stAns)
{
    int iNowTime = CMainCtrl::m_pstMain->m_iNow;

    for (int i = 0; i < stRewardTask._astRewardTasks.Size(); ++i)
    {
        CRewardTaskData& stRewardTaskData = stRewardTask._astRewardTasks[i];

        MsgAwardTaskDetail* pstMsgAwardTaskDetail = stAns.add_task_list();
        pstMsgAwardTaskDetail->set_task_type(stRewardTaskData._ucTaskType);
        pstMsgAwardTaskDetail->set_publish_gid(uiGID);
        pstMsgAwardTaskDetail->set_publish_name(CMainCtrl::m_pstMain->m_stRoleMgr.GetRoleName(uiGID));
        pstMsgAwardTaskDetail->set_publish_time(stRewardTaskData._iPublishTime);
        pstMsgAwardTaskDetail->set_get_gid(stRewardTaskData._uiAcceptGID);
        pstMsgAwardTaskDetail->set_get_name(CMainCtrl::m_pstMain->m_stRoleMgr.GetRoleName(stRewardTaskData._uiAcceptGID));
        
        if (stRewardTaskData._iPublishTime + MAX_REWARD_TASK_VALID_SEC < iNowTime)
        {
            pstMsgAwardTaskDetail->set_task_stat(3);
        }
        else
        {
            pstMsgAwardTaskDetail->set_task_stat(stRewardTaskData._ucStat);
        }
    }
}

int CTaskMgr::PublishRewardTask(CRewardTask& stRewardTask, unsigned char ucRewardType, CPlayerBaseInfo& stPlayerBaseInfo, CPlayerOnlineData& stPlayerOnlineData)
{
    int iRet = 0;
    int iNowTime = CMainCtrl::m_pstMain->m_iNow;

    //获取配置
    CRewardTaskConfigData stConfigData;
    iRet = _stRewardTaskConfig.GetConfig(ucRewardType, stConfigData);
    CHECK_RETURN(iRet);
    
    //发布等级检查
    if (stPlayerBaseInfo._shLevel < stConfigData._iPublishLevel)
    {
        return ERROR_REWARD_TASK_ERROR1;
    }

    //悬赏令判断
    if (CMainCtrl::m_pstMain->m_stStorageMgr.GetItemCount(stPlayerOnlineData._stUserStorage, ITEM_TYPE_MATERIAL, stConfigData._usPublishMaterialID) < 1)
    {
        return ERROR_REWARD_TASK_ERROR2;
    }

    //发布次数判断
    if (stRewardTask._stHasPublishCount.Get(iNowTime) 
        >= MAX_REWARD_TASK_CAN_PUBLISH_COUNT)
    {
        return ERROR_REWARD_TASK_ERROR3;
    }

    //检查是否已满
    if (_stRewardTaskList.Size() >= _stRewardTaskList.GetCount())
    {
        if ((iNowTime - _stRewardTaskList[0]._iPublishTime) > MAX_REWARD_TASK_VALID_SEC)
        {
            _stRewardTaskList.ShiftDelOneItem(0);
        }
        else
        {
            return ERROR_REWARD_TASK_ERROR4;
        }
    }

    //检查已发布是否已满
    if (stRewardTask._astRewardTasks.Size() >=
        stRewardTask._astRewardTasks.GetCount())
    {
        return ERROR_REWARD_TASK_ERROR5;
    }
    
    //扣除
    iRet = CMainCtrl::m_pstMain->m_stStorageMgr.TakeOutItem(stPlayerOnlineData._stUserStorage, ITEM_TYPE_MATERIAL, stConfigData._usPublishMaterialID, 1);
    CHECK_RETURN(iRet);

    stRewardTask._stHasPublishCount.Add(1, iNowTime);

    //发布任务
    int iPublishTime = iNowTime;
    while (1)
    {
        int i = 0;
        for (; i < stRewardTask._astRewardTasks.Size(); ++i)
        {
            if (stRewardTask._astRewardTasks[i]._iPublishTime == iPublishTime)
            {
                iPublishTime++;     //确保发布时间是唯一的
                break;
            }   
        }

        if (stRewardTask._astRewardTasks.Size() == i)
        {
            break;
        }
    }

    CRewardTaskData stTaskData;
    stTaskData._iPublishTime = iPublishTime;
    stTaskData._ucStat = 0;
    stTaskData._ucTaskType = ucRewardType;
    stTaskData._uiAcceptGID = 0;
    stRewardTask._astRewardTasks.AddOneItem(stTaskData);

    CRewardTaskListData stTask;
    stTask._ucTaskType = ucRewardType;
    stTask._iPublishTime = iPublishTime;
    stTask._uiPublishGID = stPlayerBaseInfo._uiGID;
    _stRewardTaskList.Update(stTask);
    
    return 0;
}

//接取悬赏令任务
int CTaskMgr::AcceptRewardTask(CRewardTask& stAcceptRewardTask, CRewardTask& stPublishRewardTask,
                               CPlayerOnlineData& stAcceptOnlineData, 
                               int iPublishTime, unsigned int uiPublishGID, MsgAnsAwardTask& stAns)
{
    int iRet = 0;
    int iNowTime = CMainCtrl::m_pstMain->m_iNow;

    //不能接自己发布的任务
    if (uiPublishGID == stAcceptOnlineData._uiGID)
    {
        return ERROR_REWARD_TASK_ERROR10;
    }

    //检查任务过期
    if ((iPublishTime + MAX_REWARD_TASK_VALID_SEC) < CMainCtrl::m_pstMain->m_iNow)
    {
        return ERROR_REWARD_TASK_ERROR13;
    }

    //检查次数
    if (stAcceptRewardTask._stHasAcceptCount.Get(iNowTime) >= MAX_REWARD_TASK_CAN_ACCEPT_COUNT)
    {
        return ERROR_REWARD_TASK_ERROR6;
    }

    //检查是否已经接了其他悬赏令任务
    CheckTaskExpire(stAcceptOnlineData._stUserTask);
    
    for (int i = 0; i < stAcceptOnlineData._stUserTask._astValidTasks.Size(); ++i)
    {
        CValidTask& stValidTask = stAcceptOnlineData._stUserTask._astValidTasks[i];
        if (stValidTask._stTaskID.IsRewardTask())
        {
            return ERROR_REWARD_TASK_ERROR9;
        }
    }
    
    //查找任务
    int iListIndex = -1;
    for (int i = 0; i < _stRewardTaskList.Size(); ++i)
    {
        if (_stRewardTaskList[i]._uiPublishGID == uiPublishGID
            && _stRewardTaskList[i]._iPublishTime == iPublishTime)
        {
            iListIndex = i;
            break;
        }
    }

    if (iListIndex < 0)
    {
        return ERROR_REWARD_TASK_ERROR8;
    }

    //获取配置
    CRewardTaskConfigData stConfigData;
    iRet = _stRewardTaskConfig.GetConfig(_stRewardTaskList[iListIndex]._ucTaskType, stConfigData);
    CHECK_RETURN(iRet);

    //接任务
    CTaskID stTaskID;
    stTaskID._uiBranchID = 998;
    stTaskID._uiTaskID = stConfigData._iTaskID;
    iRet = AcceptTask(stTaskID, stAcceptOnlineData._stUserTask);
    CHECK_RETURN(iRet);

    //设置返回信息
    MsgOneTask* pstMsgOneTask = stAns.mutable_get_task();
    CMainCtrl::m_pstMain->m_stTaskMgr.GetTaskInfo(stAcceptOnlineData._stUserTask, stTaskID, *pstMsgOneTask);

    //设置任务详细状态
    for (int i = 0; i < stAcceptOnlineData._stUserTask._astValidTasks.Size(); ++i)
    {
        CValidTask& stValidTask = stAcceptOnlineData._stUserTask._astValidTasks[i];
        if (stValidTask._stTaskID.IsRewardTask()
            && (int)stValidTask._stTaskID._uiTaskID == stConfigData._iTaskID)
        {
            stValidTask._iTaskEndTime = _stRewardTaskList[iListIndex]._iPublishTime + MAX_REWARD_TASK_VALID_SEC;
            stValidTask._uiPublishGID = uiPublishGID;
        }
    }

    //增加次数
    stAcceptRewardTask._stHasAcceptCount.Add(1, iNowTime);

    //设置发布者状态
    for (int i = 0; i < stPublishRewardTask._astRewardTasks.Size(); ++i)
    {
        if (stPublishRewardTask._astRewardTasks[i]._iPublishTime == iPublishTime)
        {
            CRewardTaskData& stTaskData = stPublishRewardTask._astRewardTasks[i];
            stTaskData._ucStat = 1;
            stTaskData._uiAcceptGID = stAcceptOnlineData._uiGID;
        }
    }

    //在列表中删除任务
    _stRewardTaskList.ShiftDelOneItem(iListIndex);

    return 0;
}

//提交任务
int CTaskMgr::CommitRewardTask(CTaskID& stTaskID, CRewardTask& stPublishRewardTask,
                               CPlayerOnlineData& stAcceptOnlineData)
{
    int iRet = 0;

    if (!stTaskID.IsRewardTask())
    {
        return RET_SYS_ERROR;
    }

    int iPublishTime = 0;
    for (int i = 0; i < stAcceptOnlineData._stUserTask._astValidTasks.Size(); ++i)
    {
        CValidTask& stValidTask = stAcceptOnlineData._stUserTask._astValidTasks[i];
        if (stValidTask._stTaskID.IsRewardTask()
            && stValidTask._stTaskID == stTaskID)
        {
            iPublishTime = stValidTask._iTaskEndTime - MAX_REWARD_TASK_VALID_SEC;
            break;
        }
    }

    iRet = CommitTask(stTaskID, stAcceptOnlineData._stUserTask);
    CHECK_RETURN(iRet);

    //设置发布者状态
    for (int i = 0; i < stPublishRewardTask._astRewardTasks.Size(); ++i)
    {
        if (stPublishRewardTask._astRewardTasks[i]._uiAcceptGID == stAcceptOnlineData._uiGID
            && stPublishRewardTask._astRewardTasks[i]._iPublishTime == iPublishTime)
        {
            stPublishRewardTask._astRewardTasks[i]._ucStat = 2;
        }
    }
    
    return 0;
}

int CTaskMgr::GetRewardTaskBonus(CRewardTask& stRewardTask, unsigned int uiGID, int iPublishTime, MsgAnsAwardTask& stAns)
{
    int iRet = 0;

    int iIndex = -1;
    for (int i = 0; i < stRewardTask._astRewardTasks.Size(); ++i)
    {
        if (stRewardTask._astRewardTasks[i]._iPublishTime == iPublishTime)
        {
            iIndex = i;
        }
    }

    if (iIndex < 0)
    {
        return ERROR_REWARD_TASK_ERROR7;
    }

    //检查状态
    CRewardTaskData& stTaskData = stRewardTask._astRewardTasks[iIndex];
    if (stTaskData._ucStat != 2 
        && (stTaskData._iPublishTime + MAX_REWARD_TASK_VALID_SEC) > CMainCtrl::m_pstMain->m_iNow)
    {
        return ERROR_REWARD_TASK_ERROR11;
    }

    CRewardTaskConfigData stConfigData;
    iRet = _stRewardTaskConfig.GetConfig(stTaskData._ucTaskType, stConfigData);
    CHECK_RETURN(iRet);
    
    //设置状态
    stRewardTask._astRewardTasks.DelOneItem(iIndex);

    //发放奖励
    CDropItem stDropItem;
    CDropItemData stDropItemData;

    stDropItemData.Clear();
    CMainCtrl::m_pstMain->m_stItemMgr.GetDropItemData(uiGID, ITEM_TYPE_LEVEL_EXP, 0, "", 
                                            COMM_MOD, stConfigData._iExpBonusPara, stDropItemData);
    stDropItem.Drop(stDropItemData);

    stDropItemData.Clear();
    CMainCtrl::m_pstMain->m_stItemMgr.GetDropItemData(uiGID, ITEM_TYPE_LEVEL_SILVER, 0, "", 
        COMM_MOD, stConfigData._iSilverBonusPara, stDropItemData);
    stDropItem.Drop(stDropItemData);

    CMainCtrl::m_pstMain->m_stItemMgr.DropItem(NULL, uiGID, stDropItem);

    stDropItem.GetPBMsg(uiGID, *stAns.mutable_drop());

    return 0;
}

int CTaskMgr::InitRewardTask(CRewardTask& stRewardTask, unsigned int uiGID)
{
    int iNowTime = CMainCtrl::m_pstMain->m_iNow;

    for (int i = 0; i < stRewardTask._astRewardTasks.Size(); ++i)
    {
        if ((MAX_REWARD_TASK_VALID_SEC + stRewardTask._astRewardTasks[i]._iPublishTime) > iNowTime
            && stRewardTask._astRewardTasks[i]._ucStat == 0)
        {
            CRewardTaskData& stTaskData = stRewardTask._astRewardTasks[i];
            CRewardTaskListData stTask;
            stTask._ucTaskType = stTaskData._ucTaskType;
            stTask._iPublishTime = stTaskData._iPublishTime;
            stTask._uiPublishGID = uiGID;
            _stRewardTaskList.Update(stTask);
        }
    }
    
    return 0;
}

unsigned int CTaskMgr::GetRewardTaskPublishGID(CUserTask& stUserTask, CTaskID& stTaskID)
{
    if (!stTaskID.IsRewardTask())
    {
        return 0;
    }

    for (int i = 0; i < stUserTask._astValidTasks.Size(); ++i)
    {
        if (stUserTask._astValidTasks[i]._stTaskID == stTaskID)
        {
            return stUserTask._astValidTasks[i]._uiPublishGID;
        }
    }
    
    return 0;
}
